/* *****************************************************************************

 Copyright (C) : 2000-2024, unit

 ******************************************************************************
 File Name     : SD_Card_App.c
 Version       : ver 1.0
 Author        : phh
 Created       : 2024/10/29
 Last Modified :
 Description   :
 Function List :
 History       :
 1.Date        : 2024/10/29
   Author      : phh
   Modification: Created file

***************************************************************************** */

/* ----------------------------------------------*
 * header files                                  *
 *---------------------------------------------- */
#include "SD_Card_App.h"



#include "openDML.h"
#include "osal_file.h"
#include "media.h"
#include "osal/sleep.h"
#include "osal/string.h"
#include "jpgdef.h"
#include "osal/task.h"
#include "frame.h"
#include "utlist.h"
#include "stream_frame.h"
#include "video_app.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "lib/video/dvp/cmos_sensor/csi.h"
#include "osal/semaphore.h"
#include "osal/mutex.h"
#include "hal/scale.h"
#include "hal/jpeg.h"
#include "hal/vpp.h"
#include "hal/dma.h"
#include "lib/lcd/lcd.h"

#include "custom_mem/custom_mem.h"


#include "Bsp_Data.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/* ----------------------------------------------*
 * macro                                         *
 *---------------------------------------------- */
	
#define PHOTO_COUNT 3
#define FILENAME_PREFIX "IMG_"
	
#define ERROR_MEMORY_ALLOC -1
#define ERROR_TASK_CREATE -2
	
/* ----------------------------------------------*
 * type definition                               *
 *---------------------------------------------- */
	struct AT_PHOTO
	{
		struct os_task task;
		uint32_t photo_num;
		uint8_t filename_prefix[4];
		uint8_t running;
	
	};
/* ----------------------------------------------*
 * module-wide global variables                  *
 *---------------------------------------------- */

/* ----------------------------------------------*
 * modul global variables                        *
 *---------------------------------------------- */
static struct AT_PHOTO *photo_s = NULL;
k_task_handle_t photo_thread_handle;


/* ----------------------------------------------*
 * internal routine prototypes                   *
 *---------------------------------------------- */

static void Photo_Handle_Thread(void);
static void photo_thread(void );
void test_save_photo_thread(void *d);
/* ----------------------------------------------*
 * routines' implementations                     *
 *---------------------------------------------- */








int32 test_save_photo(void)
{
    // 不再需要检查 argc 和 argv

    photo_s = custom_malloc(sizeof(struct AT_PHOTO));
    if (photo_s == NULL)
    {
        os_printf("%s: memory allocation failed\n", __FUNCTION__);
        return ERROR_MEMORY_ALLOC; // 内存分配失败时返回错误码
    }

    memset(photo_s, 0, sizeof(struct AT_PHOTO));
    photo_s->photo_num = PHOTO_COUNT; // 固定拍摄10张照片

    os_memcpy(photo_s->filename_prefix, FILENAME_PREFIX, strlen(FILENAME_PREFIX)); // 固定文件名前缀

    // 创建拍照的任务
    //OS_TASK_INIT("at_photo", &photo_s->task, test_save_photo_thread, (uint32)photo_s, OS_TASK_PRIORITY_NORMAL, 8196);
    //csi_kernel_task_new((k_task_entry_t)Photo_Handle_Thread, "Photo_Handle_Thread", (uint32)photo_s, 16, 0, NULL, 8192, &photo_thread_handle);
	
	OS_TASK_INIT("at_photo", &photo_s->task, photo_thread, (uint32)photo_s, OS_TASK_PRIORITY_NORMAL, 8196);
    return 0;
}



static int opcode_func(stream *s,void *priv,int opcode)
{
    int res = 0;
    //_os_printf("%s:%d\topcode:%d\n",__FUNCTION__,__LINE__,opcode);
    switch(opcode)
    {
    case STREAM_OPEN_ENTER:
        break;
    case STREAM_OPEN_EXIT:
    {
        enable_stream(s,1);
    }
    break;
    case STREAM_OPEN_FAIL:
        break;
    default:
        //默认都返回成功
        break;
    }
    return res;
}

extern int no_frame_record_video2(void *fp,void *d,int flen);
extern int no_frame_record_video_psram(void *fp,void *d,int flen);
void test_save_photo_thread(void *d)
{
    struct data_structure *get_f = NULL;
    struct AT_PHOTO *p_s = (struct AT_PHOTO *)d;
    stream *s = NULL;
    uint32_t flen;
    char filename[64] = {0};
    s = open_stream_available(R_RTP_JPEG,0,8,opcode_func,NULL);
    if(!s)
    {
        goto at_save_photo_thread_end;
    }
    p_s->running = 1;
    void *fp = NULL;
    uint32_t err_count = 0;
    jpeg_stream_init();

    while(p_s->photo_num && p_s->running)
    {
        get_f = recv_real_data(s);
        if(get_f)
        {
            err_count = 0;
            os_sprintf(filename,"0:/DCIM/IMG_%04d.jpg",(uint32_t)os_jiffies()%9999);
            os_printf("filename:%s\n",filename);
            fp = osal_fopen(filename,"wb+");
            if(!fp)
            {
                os_printf("osal_fopen error \n");
                goto at_save_photo_thread_end;
            }
            else
            {
                os_printf("osal_fopen success  \n");
            }
            flen = get_stream_real_data_len(get_f);
            no_frame_record_video_psram(fp,get_f,flen);
            free_data(get_f);
            get_f = NULL;
            osal_fclose(fp);
            p_s->photo_num--;
        }
        else
        {
            err_count++;
            os_sleep_ms(1);
            if(err_count++ > 1000)
            {
                os_printf("get_f error \n");
                goto at_save_photo_thread_end;
            }
        }

    }
at_save_photo_thread_end:
    if(get_f)
    {
        free_data(get_f);
        get_f = NULL;
    }

    if(s)
    {
        stop_jpeg();
        close_stream(s);
    }
    p_s->running = 0;
    custom_free((void*)p_s);
    photo_s = NULL;
}




void photo_thread(void )
{
    struct data_structure *get_f = NULL;
    stream *s = NULL;
    uint32_t flen;
    char filename[64] = {0};

    void *fp = NULL;
    uint32_t err_count = 0;
    jpeg_stream_init();

    while ( 1 )
    {
#if 1
        switch ( stPhoto.mode)
        {
        //空闲中
        case 0:
            //等待拍照按键按下
            if ( stPhoto.key==1)
            {
            	stPhoto.mode=1;
				stPhoto.key=0;
                //等待开启
                stPhoto.running=1;
				stPhoto.photo_num=1;
                //再次打开流
				s = open_stream_available(R_RTP_JPEG,0,2,opcode_func,NULL);
				if(!s)
				{
					
					os_printf("open_stream_available error \n");
					goto photo_end;
				}
				os_printf("stPhoto.mode=%d \n",stPhoto.mode);
            }
            goto photo_end;
            break;
		//拍照中
        case 1:
            //再次按下按键
			if ( stPhoto.key==1)
            {
				stPhoto.key=0;
                //进入等待再次开启
				stPhoto.running=1;
				stPhoto.photo_num++;
               
                goto photo_end;
            }
			if ( !stPhoto.running  ||  !stPhoto.photo_num )
			{
				stPhoto.mode=2;
				
				os_printf("stPhoto.mode=%d \n",stPhoto.mode);
			}
            break;
			//拍照结束
        case 2:
			//关闭流
		   if(get_f)
		   {
			   free_data(get_f);
			   get_f = NULL;
		   }
		   
		   if(s)
		   {
			   //stop_jpeg();
			   close_stream(s);
		   }
		   
		   stPhoto.running = 0;
		   stPhoto.mode=0;
		   os_printf("stPhoto.mode=%d \n",stPhoto.mode);
		   stPhoto.photo_num=0;

            break;
        default:
            break;
        }
#endif /* 1 */

        if(stPhoto.photo_num && stPhoto.running)
        {
            get_f = recv_real_data(s);
            if(get_f)
            {
                err_count = 0;
				os_sprintf(filename,"0:/DCIM/IMG_%04d.jpg",(uint32_t)os_jiffies()%9999);
                os_printf("filename:%s\n",filename);
				osal_opendir ("DCIM");
				fp = osal_fopen(filename,"wb+");
                if(!fp)
                {
                    os_printf("osal_fopen error \n");
                    goto at_save_photo_thread_end;
                }
                else
                {
                    os_printf("osal_fopen success  \n");
                }
                flen = get_stream_real_data_len(get_f);
                no_frame_record_video_psram(fp,get_f,flen);
                free_data(get_f);
                get_f = NULL;
                osal_fclose(fp);
                stPhoto.photo_num--;
            }
            else
            {
                err_count++;
                os_sleep_ms(1);
                if(err_count++ > 1000)
                {
                    os_printf("get_f error \n");
                    goto at_save_photo_thread_end;
                }
            }

        }

photo_end:
        os_sleep_ms(1);
    }

at_save_photo_thread_end:
    if(get_f)
    {
        free_data(get_f);
        get_f = NULL;
    }

    if(s)
    {
        stop_jpeg();
        close_stream(s);
    }
}















#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

